package net.ib.mtalk.network.serverapi;

import java.util.List;

import android.util.Log;

import net.ib.mntalk.protocol.Common.UUIDMsg;
import net.ib.mntalk.protocol.Common.UUIDSlicePredicate;
import net.ib.mntalk.protocol.Common.UUIDSliceRange;
import net.ib.mntalk.protocol.Session.GetViewPropertiesReq;
import net.ib.mntalk.protocol.Session.GetViewsChangesReq;
import net.ib.mntalk.protocol.Session.GetViewsReq;
import net.ib.mtalk.network.MethodId.Session;
import net.ib.mtalk.network.task.SetRemoveBuddyTask;
import net.ib.mtalk.network.NetResultReceiver;
import net.ib.mtalk.network.TcpClient;
import net.ib.mtalk.network.TcpEnvelope;

/**
 * Server-side API: ViewService<br>
 * rpc CreateView()<br>
 * rpc GetViews()<br>
 * rpc GetViewProperties()<br>
 * rpc GetViewsChanges()<br>
 * rpc RemoveViews()<br>
 * rpc AddMembers()<br>
 * rpc RemoveMembers()<br>
 * rpc GetMembers()<br>
 * @author Arngard
 */
public class ViewService {
	
	/**
	 * rpc GetViewProperties()<br>
	 * 주어진 인자로 {@link TcpEnvelope}을 만들어서 네트워크 요청까지 해 주는 래퍼 메소드. 
	 * @param req 요청의 GPB 객체
	 * @param callback 결과를 받을 콜백
	 * @return 보낼 때 사용한 Request ID
	 */
	public static int getViewProperties(GetViewPropertiesReq req, NetResultReceiver callback) {
		int reVal = TcpEnvelope.getNewRequestId();
		// TcpEnvelope!
		TcpEnvelope reqEnvelope = new TcpEnvelope.Builder()
		.setRequestId(reVal)
		.setType(TcpEnvelope.REQUEST)
		.setMethodId(Session.View.GetViewProperties)
		.setMessage(req)
		.setCallback(callback)
		.build();

		// Send!
		TcpClient.send(reqEnvelope);
		
		return reVal;
	}
	
	/**
	 * rpc GetViewProperties()<br>
	 * 주어진 인자로 {@link TcpEnvelope}을 만들어서 네트워크 요청까지 해 주는 래퍼 메소드. 
	 * @param req 요청의 GPB 객체
	 * @param callback 결과를 받을 콜백
	 * @return 보낼 때 사용한 Request ID
	 */
	public static int getViewProperties(UUIDMsg userUuid, UUIDMsg viewUuid, List<Integer> viewPropertyTypes, NetResultReceiver callback) {
		// 요청 객체를 만들고
		GetViewPropertiesReq req = new GetViewPropertiesReq();
		req.setViewUuid(viewUuid);
		if (viewPropertyTypes != null) {
			for (int value : viewPropertyTypes) {
				req.addProperty(value);
			}
		}

		// 요청한다.
		return ViewService.getViewProperties(req, callback);
	}
	
	/**
	 * rpc GetViewsChanges()<br>
	 * 주어진 인자로 {@link TcpEnvelope}을 만들어서 네트워크 요청까지 해 주는 래퍼 메소드. 
	 * @param req 요청의 GPB 객체
	 * @param callback 결과를 받을 콜백
	 * @return 보낼 때 사용한 Request ID
	 */
	public static int getViewChanges(GetViewsChangesReq req, NetResultReceiver callback) {
		int reVal = TcpEnvelope.getNewRequestId();
		
		// TcpEnvelope!
		TcpEnvelope reqEnvelope = new TcpEnvelope.Builder()
		.setRequestId(reVal)
		.setType(TcpEnvelope.REQUEST)
		.setMethodId(Session.View.GetViewsChanges)
		.setMessage(req)
		.setCallback(callback)
		.build();

		// Send!
		TcpClient.send(reqEnvelope);
		
		return reVal;
	}
	
	/**
	 * rpc GetViewsChanges()<br>
	 * 주어진 인자로 {@link TcpEnvelope}을 만들어서 네트워크 요청까지 해 주는 래퍼 메소드. 
	 * @param uuidMsg (요청 객체의 구성요소)
	 * @param range (요청 객체의 구성요소)
	 * @param callback 결과를 받을 콜백
	 * @return 보낼 때 사용한 Request ID
	 */
	public static int getViewChanges(UUIDMsg uuidMsg, UUIDSliceRange range, NetResultReceiver callback) {
		
		// 요청 객체를 만들고
		GetViewsChangesReq req = new GetViewsChangesReq();
		req.setRange(range);

		// 요청한다.
		return ViewService.getViewChanges(req, callback);
	}
	
	/**
	 * rpc GetViews()<br>
	 * 뷰의 정보를 얻어 온다.
	 * 주어진 인자로 {@link TcpEnvelope}을 만들어서 네트워크 요청까지 해 주는 래퍼 메소드. 
	 * @param getViewsReq viewReq 요청 GPB 객체
	 * @param callback 결과를 받을 콜백
	 * @return 보낼 때 사용한 Request ID
	 */
	public static int getViews(GetViewsReq getViewsReq, NetResultReceiver callback){
		int reVal = TcpEnvelope.getNewRequestId();
		
		// TcpEnvelope!
		TcpEnvelope reqEnvelope = new TcpEnvelope.Builder()
		.setRequestId(reVal)
		.setType(TcpEnvelope.REQUEST)
		.setMethodId(Session.View.GetViews)
		.setMessage(getViewsReq)
		.setCallback(callback)
		.build();
		
		// Send!
		TcpClient.send(reqEnvelope);
		
		return reVal;
	}
	
	public static int getViews(UUIDMsg viewUuidMsg, NetResultReceiver callback){
		
		// 요청 객체를 만들고
		GetViewsReq getViewsReq = new GetViewsReq();
		
		UUIDSlicePredicate uuidSlicePredicate = new UUIDSlicePredicate();
		uuidSlicePredicate.addId(viewUuidMsg);
		
		getViewsReq.setPredicate(uuidSlicePredicate);
		
		// 요청한다.
		return ViewService.getViews(getViewsReq, callback);
	}
}
